// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.ai.states;

import zombie.ai.State;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.characters.ZombieThumpManager;
import zombie.core.PerformanceSettings;
import zombie.core.Rand;
import zombie.core.skinnedmodel.advancedanimation.AnimEvent;
import zombie.iso.IsoChunk;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoMovingObject;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.iso.LosUtil;
import zombie.iso.objects.IsoBarricade;
import zombie.iso.objects.IsoDoor;
import zombie.iso.objects.IsoThumpable;
import zombie.iso.objects.IsoWindow;
import zombie.iso.objects.interfaces.Thumpable;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerMap;
import zombie.network.ServerOptions;
import zombie.util.Type;
import zombie.vehicles.BaseVehicle;

public final class ThumpState extends State {
    private static final ThumpState _instance = new ThumpState();

    public static ThumpState instance() {
        return _instance;
    }

    @Override
    public void enter(IsoGameCharacter owner) {
        if (!GameClient.bClient || owner.isLocal()) {
            switch (Rand.Next(3)) {
                case 0:
                    owner.setVariable("ThumpType", "DoorClaw");
                    break;
                case 1:
                    owner.setVariable("ThumpType", "Door");
                    break;
                case 2:
                    owner.setVariable("ThumpType", "DoorBang");
            }
        }

        if (GameClient.bClient && owner.isLocal()) {
            GameClient.sendThump(owner, owner.getThumpTarget());
        }
    }

    @Override
    public void execute(IsoGameCharacter owner) {
        IsoZombie isoZombie = (IsoZombie)owner;
        Thumpable thumpable0 = owner.getThumpTarget();
        if (thumpable0 instanceof IsoObject) {
            owner.faceThisObject((IsoObject)thumpable0);
        }

        boolean boolean0 = GameServer.bServer && GameServer.bFastForward || !GameServer.bServer && IsoPlayer.allPlayersAsleep();
        if (boolean0 || owner.actionContext.hasEventOccurred("thumpframe")) {
            owner.actionContext.clearEvent("thumpframe");
            owner.setTimeThumping(owner.getTimeThumping() + 1);
            if (isoZombie.TimeSinceSeenFlesh < 5.0F) {
                owner.setTimeThumping(0);
            }

            int int0 = 1;
            if (owner.getCurrentSquare() != null) {
                int0 = owner.getCurrentSquare().getMovingObjects().size();
            }

            for (int int1 = 0; int1 < int0 && this.isThumpTargetValid(owner, owner.getThumpTarget()); int1++) {
                owner.getThumpTarget().Thump(owner);
            }

            Thumpable thumpable1 = owner.getThumpTarget() == null ? null : owner.getThumpTarget().getThumpableFor(owner);
            boolean boolean1 = GameServer.bServer || zombie.SoundManager.instance.isListenerInRange(owner.x, owner.y, 20.0F);
            if (boolean1 && !IsoPlayer.allPlayersAsleep()) {
                if (thumpable1 instanceof IsoWindow) {
                    isoZombie.setThumpFlag(Rand.Next(3) == 0 ? 2 : 3);
                    isoZombie.setThumpCondition(thumpable1.getThumpCondition());
                    if (!GameServer.bServer) {
                        ZombieThumpManager.instance.addCharacter(isoZombie);
                    }
                } else if (thumpable1 != null) {
                    String string = "ZombieThumpGeneric";
                    IsoBarricade isoBarricade = Type.tryCastTo(thumpable1, IsoBarricade.class);
                    if (isoBarricade == null || !isoBarricade.isMetal() && !isoBarricade.isMetalBar()) {
                        if (thumpable1 instanceof IsoDoor) {
                            string = ((IsoDoor)thumpable1).getThumpSound();
                        } else if (thumpable1 instanceof IsoThumpable) {
                            string = ((IsoThumpable)thumpable1).getThumpSound();
                        }
                    } else {
                        string = "ZombieThumpMetal";
                    }

                    if ("ZombieThumpGeneric".equals(string)) {
                        isoZombie.setThumpFlag(1);
                    } else if ("ZombieThumpWindow".equals(string)) {
                        isoZombie.setThumpFlag(3);
                    } else if ("ZombieThumpMetal".equals(string)) {
                        isoZombie.setThumpFlag(4);
                    } else if ("ZombieThumpGarageDoor".equals(string)) {
                        isoZombie.setThumpFlag(5);
                    } else {
                        isoZombie.setThumpFlag(1);
                    }

                    isoZombie.setThumpCondition(thumpable1.getThumpCondition());
                    if (!GameServer.bServer) {
                        ZombieThumpManager.instance.addCharacter(isoZombie);
                    }
                }
            }
        }

        if (!this.isThumpTargetValid(owner, owner.getThumpTarget())) {
            owner.setThumpTarget(null);
            owner.setTimeThumping(0);
            if (thumpable0 instanceof IsoWindow && ((IsoWindow)thumpable0).canClimbThrough(owner)) {
                owner.climbThroughWindow((IsoWindow)thumpable0);
            } else {
                if (thumpable0 instanceof IsoDoor && (((IsoDoor)thumpable0).open || thumpable0.isDestroyed())) {
                    IsoDoor isoDoor = (IsoDoor)thumpable0;
                    IsoGridSquare isoGridSquare0 = isoDoor.getSquare();
                    IsoGridSquare isoGridSquare1 = isoDoor.getOppositeSquare();
                    if (this.lungeThroughDoor(isoZombie, isoGridSquare0, isoGridSquare1)) {
                        return;
                    }
                }

                if (thumpable0 instanceof IsoThumpable && ((IsoThumpable)thumpable0).isDoor && (((IsoThumpable)thumpable0).open || thumpable0.isDestroyed())) {
                    IsoThumpable isoThumpable = (IsoThumpable)thumpable0;
                    IsoGridSquare isoGridSquare2 = isoThumpable.getSquare();
                    IsoGridSquare isoGridSquare3 = isoThumpable.getInsideSquare();
                    if (this.lungeThroughDoor(isoZombie, isoGridSquare2, isoGridSquare3)) {
                        return;
                    }
                }

                if (isoZombie.LastTargetSeenX != -1) {
                    owner.pathToLocation(isoZombie.LastTargetSeenX, isoZombie.LastTargetSeenY, isoZombie.LastTargetSeenZ);
                }
            }
        }
    }

    @Override
    public void exit(IsoGameCharacter owner) {
        owner.setThumpTarget(null);
        ((IsoZombie)owner).setThumpTimer(200);
        if (GameClient.bClient && owner.isLocal()) {
            GameClient.sendThump(owner, owner.getThumpTarget());
        }
    }

    @Override
    public void animEvent(IsoGameCharacter owner, AnimEvent event) {
        if (event.m_EventName.equalsIgnoreCase("ThumpFrame")) {
        }
    }

    private IsoPlayer findPlayer(int int4, int int5, int int1, int int2, int int6) {
        for (int int0 = int1; int0 <= int2; int0++) {
            for (int int3 = int4; int3 <= int5; int3++) {
                IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare(int3, int0, int6);
                if (isoGridSquare != null) {
                    for (int int7 = 0; int7 < isoGridSquare.getMovingObjects().size(); int7++) {
                        IsoMovingObject isoMovingObject = (IsoMovingObject)isoGridSquare.getMovingObjects().get(int7);
                        if (isoMovingObject instanceof IsoPlayer && !((IsoPlayer)isoMovingObject).isGhostMode()) {
                            return (IsoPlayer)isoMovingObject;
                        }
                    }
                }
            }
        }

        return null;
    }

    private boolean lungeThroughDoor(IsoZombie isoZombie, IsoGridSquare isoGridSquare1, IsoGridSquare isoGridSquare0) {
        if (isoGridSquare1 != null && isoGridSquare0 != null) {
            boolean _boolean = isoGridSquare1.getY() > isoGridSquare0.getY();
            IsoGridSquare isoGridSquare2 = null;
            IsoPlayer isoPlayer = null;
            if (isoZombie.getCurrentSquare() == isoGridSquare1) {
                isoGridSquare2 = isoGridSquare0;
                if (_boolean) {
                    isoPlayer = this.findPlayer(
                        isoGridSquare0.getX() - 1, isoGridSquare0.getX() + 1, isoGridSquare0.getY() - 1, isoGridSquare0.getY(), isoGridSquare0.getZ()
                    );
                } else {
                    isoPlayer = this.findPlayer(
                        isoGridSquare0.getX() - 1, isoGridSquare0.getX(), isoGridSquare0.getY() - 1, isoGridSquare0.getY() + 1, isoGridSquare0.getZ()
                    );
                }
            } else if (isoZombie.getCurrentSquare() == isoGridSquare0) {
                isoGridSquare2 = isoGridSquare1;
                if (_boolean) {
                    isoPlayer = this.findPlayer(
                        isoGridSquare1.getX() - 1, isoGridSquare1.getX() + 1, isoGridSquare1.getY(), isoGridSquare1.getY() + 1, isoGridSquare1.getZ()
                    );
                } else {
                    isoPlayer = this.findPlayer(
                        isoGridSquare1.getX(), isoGridSquare1.getX() + 1, isoGridSquare1.getY() - 1, isoGridSquare1.getY() + 1, isoGridSquare1.getZ()
                    );
                }
            }

            if (isoPlayer != null
                && !LosUtil.lineClearCollide(
                    isoGridSquare2.getX(),
                    isoGridSquare2.getY(),
                    isoGridSquare2.getZ(),
                    (int)isoPlayer.getX(),
                    (int)isoPlayer.getY(),
                    (int)isoPlayer.getZ(),
                    false
                )) {
                isoZombie.setTarget(isoPlayer);
                isoZombie.vectorToTarget.x = isoPlayer.getX();
                isoZombie.vectorToTarget.y = isoPlayer.getY();
                isoZombie.vectorToTarget.x = isoZombie.vectorToTarget.x - isoZombie.getX();
                isoZombie.vectorToTarget.y = isoZombie.vectorToTarget.y - isoZombie.getY();
                isoZombie.TimeSinceSeenFlesh = 0.0F;
                isoZombie.setThumpTarget(null);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static int getFastForwardDamageMultiplier() {
        zombie.GameTime gameTime = zombie.GameTime.getInstance();
        if (GameServer.bServer) {
            return (int)(GameServer.bFastForward ? ServerOptions.instance.FastForwardMultiplier.getValue() / (double)gameTime.getDeltaMinutesPerDay() : 1.0);
        } else if (GameClient.bClient) {
            return (int)(GameClient.bFastForward ? ServerOptions.instance.FastForwardMultiplier.getValue() / (double)gameTime.getDeltaMinutesPerDay() : 1.0);
        } else {
            return IsoPlayer.allPlayersAsleep() ? (int)(200.0F * (30.0F / (float)PerformanceSettings.getLockFPS()) / 1.6F) : (int)gameTime.getTrueMultiplier();
        }
    }

    private boolean isThumpTargetValid(IsoGameCharacter isoGameCharacter, Thumpable thumpable) {
        if (thumpable == null) {
            return false;
        } else if (thumpable.isDestroyed()) {
            return false;
        } else {
            IsoObject isoObject = Type.tryCastTo(thumpable, IsoObject.class);
            if (isoObject == null) {
                return false;
            } else if (thumpable instanceof BaseVehicle) {
                return isoObject.getMovingObjectIndex() != -1;
            } else if (isoObject.getObjectIndex() == -1) {
                return false;
            } else {
                int int0 = isoObject.getSquare().getX() / 10;
                int int1 = isoObject.getSquare().getY() / 10;
                IsoChunk isoChunk = GameServer.bServer ? ServerMap.instance.getChunk(int0, int1) : IsoWorld.instance.CurrentCell.getChunk(int0, int1);
                return isoChunk == null ? false : thumpable.getThumpableFor(isoGameCharacter) != null;
            }
        }
    }
}
